import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: wh(1835734390 @ qq.com)
 * @date: 2023/2/22 11:16
 * @description:
 * @version:
 */

/**
 * 个人理解：相当于使用stream流会发生浅拷贝，对于引用类型，会直接复制引用，所以过滤或者映射后的新集合，如果再对其进行修改，会改变原集合的属性。
 * 但是，如果对新的集合只是增加或者删除元素，不会对原集合有影响
 */
public class TestLambda {

    public static void main(String[] args) {
        List<UserInfo> userInfoList = new ArrayList<>();
        userInfoList.add(new UserInfo(1L, "捡田螺的小男孩", 18,null));
        userInfoList.add(new UserInfo(2L, "程序员田螺", 27,null));
        userInfoList.add(new UserInfo(3L, "捡瓶子的小男孩", 26,null));
        UserInfo userInfo22 = new UserInfo(null,null,null,null);

        List<UserInfo> tmpCollect1 = userInfoList.stream().map(y -> {
            y.setAge(y.getAge() + 2);
            return y;
        }).collect(Collectors.toList());
        List<UserInfo> tmpCollect4 = userInfoList.stream().filter(x -> {
            x.setAge(x.age - 1);
            if (x.getAge() > 20) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());

        List<UserInfo> tmpCollect2 = userInfoList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toList());


       /* AtomicInteger count = new AtomicInteger(10);
        userInfoList.stream().filter(item -> {
            if (item.getAge() > count.get()) {
                count.getAndIncrement();
                item.setAge(count.get());
            }
            return true;
        });
        */

        UserInfo tmp = new UserInfo(4L,"ksksks",99,null);


        Integer x = new Integer(0);
        boolean test1 = test(tmp,x);
        System.out.println(x);
        System.out.println(tmp.getCity());



        Predicate<UserInfo> predicate = (userInfo) -> userInfo.getUserName().contains("男孩") || userInfo.getAge() == 27;
        List<UserInfo> collect1 = userInfoList.stream().filter(predicate).collect(Collectors.toList());
        /**
         *  list 转 map
         *  使用Collectors.toMap的时候，如果有可以重复会报错，所以需要加(k1, k2) -> k1
         *  (k1, k2) -> k1 表示，如果有重复的key,则保留第一个，舍弃第二个
         */
        Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId, userInfo -> userInfo, (k1, k2) -> k1));
        userInfoMap.values().forEach(a->System.out.println(a.toString()));

        System.out.println("=============================================>");
        /**
         * filter 过滤，留下超过18岁的用户
         * 添加结构体后，若返回true表示符合过滤条件，否则表示不符合
         */
        //List<UserInfo> userInfoResultList = userInfoList.stream().filter(user -> user.getAge() > 18).collect(Collectors.toList());
        List<UserInfo> userInfoResultList = userInfoList.stream().filter(user -> {
            if (user.age > 18) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());
        userInfoResultList.forEach(a -> System.out.println(a.toString()));


        System.out.println("==============================================>");

        String test = "testwhsss";
        String[] str = new String[2];
        if (test.contains(".")) {
            str = test.split("\\.");
        } else {
            str[1] = test;
        }



       // List<UserInfo> collect1 = userInfoList.stream().filter(item -> item.getUserName().contains(null)).collect(Collectors.toList());


        /**
         * forEach 遍历集合List列表
         */
        List<String> userNameList = Arrays.asList("捡田螺的小男孩", "程序员田螺", "捡瓶子的小男孩");
        userNameList.forEach(System.out::println);

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("公众号", "捡田螺的小男孩");
        hashMap.put("职业", "程序员田螺");
        hashMap.put("昵称", "捡瓶子的小男孩");
        /**
         *  forEach 遍历集合Map
         */
        hashMap.forEach((k, v) -> System.out.println(k + ":\t" + v));
        System.out.println("====================================================>");


        List<UserInfo> originUserInfoList = new ArrayList<>();
        originUserInfoList.add(new UserInfo(1L, "捡田螺的小男孩", 18,"深圳"));
        originUserInfoList.add(new UserInfo(2L, "程序员田螺", 27,"深圳"));
        originUserInfoList.add(new UserInfo(5L, "程序员田螺2", 27,"深圳"));
        originUserInfoList.add(new UserInfo(6L, "捡破烂的小男孩2", 29,"湛江"));
        originUserInfoList.add(new UserInfo(3L, "捡瓶子的小男孩", 26,"湛江"));
        originUserInfoList.add(new UserInfo(4L, "捡破烂的小男孩", 29,"湛江"));
        /**
         * 传统分组做法
         */
        Map<String, List<UserInfo>> result = new HashMap<>();
        for (UserInfo userInfo : originUserInfoList) {
            String city = userInfo.getCity();
            List<UserInfo> userInfos = result.get(city);
            if (userInfos == null) {
                userInfos = new ArrayList<>();
                result.put(city, userInfos);
            }
            userInfos.add(userInfo);
        }
        /**
         * 新方法
         */
        Map<String, List<UserInfo>> resultNew = originUserInfoList.stream()
                .collect(Collectors.groupingBy(UserInfo::getCity,LinkedHashMap::new,Collectors.toList()));

        System.out.println("========================================>");
        /**
         *  sorted + Comparator.comparing 排序列表，
         */
        userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge)).collect(Collectors.toList());
        userInfoList.forEach(a -> System.out.println(a.toString()));

        System.out.println("开始降序排序");

        /**
         * 如果想降序排序，则可以使用加reversed()
         */
        userInfoList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getAge).reversed()).collect(Collectors.toList());
        userInfoList.forEach(a -> System.out.println(a.toString()));

        System.out.println("=========================================>");
        /**
         * distinct去重
         */
        List<String> list = Arrays.asList("A", "B", "F", "A", "C");
        List<String> temp = list.stream().distinct().collect(Collectors.toList());
        temp.forEach(System.out::println);

        /**
         *  findFirst 返回第一个
         */
        List<String> list2 = Arrays.asList("A", "B", "F", "A", "C");
        list2.stream().findFirst().ifPresent(System.out::println);
        /**
         * anyMatch是否至少匹配一个元素
         */
        Stream<String> stream = Stream.of("A", "B", "C", "D");
        boolean match = stream.anyMatch(s -> s.contains("C"));
        System.out.println(match);

        /**
         * allMatch 匹配所有元素
         */
   /*     Stream<String> stream2 = Stream.of("A", "B", "C", "D");
        boolean match2 = stream.allMatch(s -> s.contains("C"));
        System.out.println(match2);*/
        /**
         * map转换
         */
        List<String> list3 = Arrays.asList("jay", "tianluo");
        //转化为大写
        List<String> upperCaselist = list3.stream().map(String::toUpperCase).collect(Collectors.toList());
        upperCaselist.forEach(System.out::println);

        /**
         * flatMap()将多个stream流合并成一个stream
         */
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(3);
        arrayList.add(22);
        arrayList.add(11);
        arrayList.add(44);
        arrayList.add(null);
        arrayList.add(4);
        lists.add(arrayList);
        List<Integer> arrayList2 = new ArrayList<>();
        arrayList2.add(-1);
        arrayList2.add(-3);
        arrayList2.add(-22);
        arrayList2.add(-11);
        arrayList2.add(-44);
        arrayList2.add(null);
        arrayList2.add(-4);
        lists.add(arrayList2);
        //将子集合抽上来形成一个大集合
        List<Integer> collect = lists.stream().flatMap(item -> item.stream().filter(Objects::nonNull))
                .collect(Collectors.toList());
        List<Integer> collect2 = new ArrayList<>();
        lists.forEach(item -> item.stream().filter(Objects::nonNull).forEach(vo ->collect2.add(vo)));
        System.out.println(collect2);
        System.out.println(collect);
    }


    public static boolean test(UserInfo userInfo,Integer x) {
        userInfo.setCity("ksks");
        return true;
    }

    public static class UserInfo{
        private Long UserId;
        private String UserName;
        private Integer age;
        private String city;

        public Long getUserId() {
            return UserId;
        }

        public void setUserId(Long userId) {
            UserId = userId;
        }

        public String getUserName() {
            return UserName;
        }

        public void setUserName(String userName) {
            UserName = userName;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public UserInfo(Long userId, String userName, Integer age, String city) {
            UserId = userId;
            UserName = userName;
            this.age = age;
            this.city = city;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "UserId=" + UserId +
                    ", UserName='" + UserName + '\'' +
                    ", age=" + age +
                    ", city='" + city + '\'' +
                    '}';
        }
    }

}

